using System;
using System.Collections.Generic;
using System.Text;

namespace DartsDetector.Classes.Games.Base
{
    public enum Game
    {
        Game301,
        Game501,
        MickeyMouse
    }

    //public delegate void BeforeChangePlayerIndex(GameBase sender);  

    public abstract class GameBase
    {
        #region Private properties
        private List<Turns> _PlayerTurns = new List<Turns>();
        private int _NumberOfPlayers = 2;
        private Game _GameType = Game.Game501;
        private int _ActivePlayerIndex = 0;

        private List<ThrownDarts> _PlayerThrows = new List<ThrownDarts>();
        private int _ThowNumber = 0;
        #endregion

        #region Constructor(s)
        public GameBase(Game gameType, int numberOfPlayers)
        {
            _NumberOfPlayers = numberOfPlayers;
            _GameType = gameType;

            for (int i = 0; i < _NumberOfPlayers; i++)
            {
                _PlayerTurns.Add(new Turns());
                _PlayerThrows.Add(new ThrownDarts());
            }
        }
        #endregion

        #region Public properties
        public List<Turns> PlayerTurns
        {
            get { return _PlayerTurns; }
            set { _PlayerTurns = value; }
        }
        public int NumberOfPlayers
        {
            get { return _NumberOfPlayers; }
            set { _NumberOfPlayers = value; }
        }
        public Game GameType
        {
            get { return _GameType; }
            set { _GameType = value; }
        }
        public int ActivePlayerIndex
        {
            get { return _ActivePlayerIndex; }
            set { _ActivePlayerIndex = value; }
        }

        public int BeginScore
        {
            get
            {
                int value = 0;
                switch (this._GameType)
                {
                    case Game.Game301: value = 301; break;
                    case Game.Game501: value = 501; break;
                }
                return value;
            }
        }

        public List<ThrownDarts> PlayerThrows
        {
            get { return _PlayerThrows; }
        }
        #endregion

        /// <summary>
        /// Throw the dart.
        /// </summary>
        /// <param name="score">The score.</param>
        public void DartThrown(int score)
        {
            _PlayerThrows[_ActivePlayerIndex].DartScores.Add(score);
            _PlayerThrows[_ActivePlayerIndex].DartTimes.Add(DateTime.Now);
            _ThowNumber++;

            if (_ThowNumber >= 3)//Done throwing darts this turn
            {
                this.PlayerTurns[this.ActivePlayerIndex].Add(_PlayerThrows[_ActivePlayerIndex]);
                ChangePlayerIndex();
            }
        }

        /// <summary>
        /// Changes the index of the player.
        /// </summary>
        public void ChangePlayerIndex()
        {
            //OnBeforeChangePlayerIndex(this);            

            _ActivePlayerIndex++;
            if (_ActivePlayerIndex >= _NumberOfPlayers)
                _ActivePlayerIndex = 0;

            _ThowNumber = 0;
            _PlayerThrows[_ActivePlayerIndex] = new ThrownDarts();
        }

        //public event BeforeChangePlayerIndex OnBeforeChangePlayerIndex;
            
    }

    public class Turns : List<ThrownDarts>
    {
        public int TotalScore
        {
            get
            {
                int _TotalScore = 0;
                foreach (ThrownDarts t in this)
                    _TotalScore += t.TotalScore;
                return _TotalScore;
            }
        }
    }

    public class ThrownDarts
    {
        #region Private properties
        private List<int> _DartScores = new List<int>(3);
        private List<DateTime> _DartTimes = new List<DateTime>(3);
        #endregion

        #region Constructor(s)
        public ThrownDarts()
        { }
        #endregion

        #region Public properties
        public List<int> DartScores
        {
            get { return _DartScores; }
            set { _DartScores = value; }
        }

        public List<DateTime> DartTimes
        {
            get { return _DartTimes; }
            set { _DartTimes = value; }
        }

        public int TotalScore
        {
            get
            {
                int score = 0;
                foreach (int i in _DartScores)
                    score += i;
                return score;
            }
        }
        #endregion
    }
}
